import { CodeGenerator, Interface, Property, Surrounding } from 'pont-engine';

/**
 * 生成代码
 */
export default class MyGenerator extends CodeGenerator {

  /**
   * 类型声明 api.d.ts
   */

  /** 获取公共的类型定义代码 */
  // getCommonDeclaration() {
  //   return `
  //   import { RequestOptionsInit } from 'umi-request';
  //   `;
  // }

  /** 获取所有基类的类型定义代码，一个 namespace */
  getBaseClassesInDeclaration() {
    const content = `namespace ${this.dataSource.name || 'defs'} {
      ${this.dataSource.baseClasses
        .map(
          base => `
        export ${this.getBaseClassInDeclaration(base)}
      `
        )
        .join('\n')}
    }
    `;

    return content;
  }

  /** 获取接口内容的类型定义代码 */
  getInterfaceContentInDeclaration(inter: Interface) {
    // 请求体（Body）类型参数列表
    const bodyParams = inter.parameters.filter((param) => param.in === 'body');
    // 路径参数（PathVariable）类型参数列表
    const pathParams = inter.parameters.filter((param) => param.in === 'path');
    // 查询字符串（QueryString）类型参数列表
    const queryParams = inter.parameters.filter((param) => param.in === 'query');

    // 获取请求体类型参数类代码
    const bodyParamsCode = inter.getBodyParamsCode();
    // 获取查询字符串参数类代码
    const paramsCode = inter.getParamsCode();
    // 获取路径参数类代码
    const pathParamsCode = this.getPathParamsCodeInDeclaration(pathParams);

    // 接口方法参数列表
    const requestArgs: string[] = [];

    pathParams.length > 0 && requestArgs.push(`pathParams: PathParams`);
    queryParams.length > 0 && requestArgs.push(`params: Params`);
    bodyParams.length > 0 && requestArgs.push(`bodyParams:${ bodyParams.length > 0 ? bodyParamsCode : '' }`);
    requestArgs.push('options?: WechatMiniprogram.RequestOption');

    const requestParams = requestArgs.join(', ');

    // 返回数据类型
    const {responseType} = inter;

    return `
      ${queryParams.length > 0 ? paramsCode : ''}
      ${pathParams.length > 0 ? pathParamsCode : ''}

      export type ResponseType = Promise<${responseType}>

      export const URL:string;

      export function request(${requestParams}): ResponseType;
    `;
  }

  /**
   * 全局入口文件 index.ts
   */
  getIndex() {
    // let conclusion = `
    //   export * from './mods/';
    // `;

    // dataSource name means multiple dataSource
    // if (this.dataSource.name) {
    //   conclusion = `
    //     export { ${this.dataSource.name} } from './mods/';
    //   `;
    // }

    return `
      import * as defs from './baseClass';
      import API from './mods/index';

      export default {
        defs: defs,
        API: API
      }
    `;
  }

  /**
   * 模块入口文件 /mods/index.ts
   */
  getModsIndex() {
    let conclusion = `
    export default {
        ${this.dataSource.mods.map(mod => mod.name).join(', \n')}
      };
    `;

    // let conclusion = `
    //   export const API = {
    //     ${this.dataSource.mods.map(mod => mod.name).join(', \n')}
    //   };
    // `;

    // dataSource name means multiple dataSource
    // if (this.dataSource.name) {
    //   conclusion = `
    //     export const ${this.dataSource.name} = {
    //       ${this.dataSource.mods.map(mod => mod.name).join(', \n')}
    //     };
    //   `;
    // }

    return `
      ${this.dataSource.mods
        .map(mod => {
          return `import * as ${mod.name} from './${mod.name}/index';`;
        })
        .join('\n')}
      ${conclusion}
    `;
  }

  // getModIndex(mod: Mod) {
    
  //   return `/**
  //     * @description ${mod.description}
  //     */
  //   ${ (mod.interfaces || []).map((inter) => {
  //     return `import * as ${ inter.name } from './${ inter.name }/index';`
  //   }) }
    
  //   export {
  //     ${
  //       (mod.interfaces || []).map((inter) => {
  //         return inter.name
  //       }).join(',')
  //     }
  //   };
  //   `;
  // }

  /**
   * 接口实现 /mods/<module_name>/<method_name>.ts
   */

  /** 获取接口实现内容的代码 */
  getInterfaceContent(inter: Interface) {
    // 接口请求类型
    const method = inter.method.toUpperCase();

    // 请求体（Body）类型参数列表
    const bodyParams = inter.parameters.filter((param) => param.in === 'body');
    // 路径参数（PathVariable）类型参数列表
    const pathParams = inter.parameters.filter((param) => param.in === 'path');
    // 查询字符串（QueryString）类型参数列表
    const queryParams = inter.parameters.filter((param) => param.in === 'query');

    // 获取请求体类型参数类代码
    const bodyParamsCode = inter.getBodyParamsCode();
    // 获取查询字符串参数类代码
    const paramsCode = this.getParamsCode(queryParams);
    // 获取路径参数类代码
    const pathParamsCode = this.getPathParamsCode(pathParams);

    // 返回数据类型
    const {responseType} = inter;

    // 请求的 MIME 类型
    const contentType = inter.consumes && inter.consumes.length ? inter.consumes[0] : 'application/json';
    
    // 接口方法参数列表
    const requestArgs: string[] = [];

    pathParams.length > 0 && requestArgs.push(`pathParams: PathParams`);
    queryParams.length > 0 && requestArgs.push(`params: Params`);
    bodyParams.length > 0 && requestArgs.push(`bodyParams:${ bodyParams.length > 0 ? bodyParamsCode : '' }`);
    requestArgs.push('options?: WechatMiniprogram.RequestOption');

    const requestParams = requestArgs.join(', ');

    // 数据源前缀
    let dataSourcePrefix = '';
    if (this.dataSource.name) {
      dataSourcePrefix = `/${this.dataSource.name}`
    }
    
    let pathParamsHandleCode = '';

    if (pathParams.length > 0 ) {
      pathParamsHandleCode = `
        for (let key in pathParams) {
          url.replace('{' + key + '}', pathParams[key]);
        }
      `;
    }

    return `
      import { fetch } from '../../../utils/util';

      ${ pathParams.length > 0 ? `export ${ pathParamsCode }` : '' }
      ${ queryParams.length > 0 ? `export ${ paramsCode }` : '' }

      export type ResponseType = Promise<${responseType}>;

      export const URL = '${dataSourcePrefix}${inter.path}';

      /**
       * @desc ${inter.description}
       */
      export function request (${requestParams}):ResponseType {
        let url = '${dataSourcePrefix}${inter.path}';

        ${pathParamsHandleCode}

        const fetchOption = Object.assign ({
          url: url,
          method: '${method}',
          headers: {
            'Content-Type': '${contentType}'
          },
          ${ queryParams.length > 0 ? 'params: params,' : '' }
          ${ bodyParamsCode ? 'data: bodyParams' : '' }
        },
        options)
        return fetch(fetchOption);
      }
      `;
  }

  // 生成参数类（Params）
  getParamsCode(params: Property[]):string {
    if (!Array.isArray(params) || params.length === 0) return '';

    return `
      export class Params {
        ${ params.map((param) => {
          return `${ param.toPropertyCode().replace(":", "?:") }`
        }).join('\n') }
      }
    `;
  }

  // 生成路径参数类（PathParams）
  getPathParamsCode(pathParams: Property[]):string {
    if (!Array.isArray(pathParams) || pathParams.length === 0) return '';

    return `
      class PathParams {
        ${ pathParams.map((param) => {
          return `${ param.toPropertyCodeWithInitValue("") };`
        }).join('\n') }

        [key:string]: any
      }
    `;
  }

  // 生成路径参数类（PathParams）
  getPathParamsCodeInDeclaration(pathParams: Property[]):string {
    if (!Array.isArray(pathParams) || pathParams.length === 0) return '';

    return `
      class PathParams {
        ${ pathParams.map((param) => {
          return `${ param.toPropertyCode(Surrounding.typeScript, param.required) }`
        }).join('\n') }

        [key:string]: any
      }
    `;
  }

}